package uns.fit.gis.rms;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Vector;

import javax.microedition.rms.InvalidRecordIDException;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreNotFoundException;
import javax.microedition.rms.RecordStoreNotOpenException;

import uns.fit.gis.MapDrawer;
import uns.fit.gis.Util;
import uns.fit.gis.mapdrawer.LayerConfig;
import uns.fit.gis.mapdrawer.MapCanvas;
import uns.fit.gis.mapobj.SimpleLocation;

public class RSManager {
	private static RecordStore rs;
	public static void open(String name) {
		try {
			rs = RecordStore.openRecordStore(name, true);
			System.out.println("OPEN " + rs.getName() + " " + rs.getNumRecords());
		}
		catch (RecordStoreException rse) {
			rse.printStackTrace();
		}
	}
	
	public static void close() {
		if(rs != null) {
			try {
				System.out.println("CLOSE " + rs.getName() + " " + rs.getNumRecords());
				rs.closeRecordStore();
			}
			catch (RecordStoreNotOpenException rsnoe) {
				rsnoe.printStackTrace();
			}
			catch(RecordStoreException rse) {
				rse.printStackTrace();
			}
		}
	}
	
	public static void addRecord(byte[] data) {
		if(rs != null) {
			try {
				rs.addRecord(data, 0, data.length);
			}
			catch(RecordStoreException rse) {
				rse.printStackTrace();
			}
		}
	}
	
	public static byte[] getRecord(int id) {
		if(rs != null) {
			try {
				return rs.getRecord(id);
			}
			catch(RecordStoreNotOpenException rsnoe) {
				rsnoe.printStackTrace();
			}
			catch(InvalidRecordIDException iride) {
				iride.printStackTrace();
			}
			catch(RecordStoreException rse) {
				rse.printStackTrace();
			}
		}
		return null;
	}
	/*
	public static void deleteRecord (int id) {
		if(rs != null) {
			try {
				rs.deleteRecord(id);
			}
			catch(RecordStoreNotOpenException rsnoe) {
				rsnoe.printStackTrace();
			}
			catch(InvalidRecordIDException iride) {
				iride.printStackTrace();
			}
			catch(RecordStoreException rse) {
				rse.printStackTrace();
			}
			catch(SecurityException se) {
				se.printStackTrace();
			}
		}
	}
	*/
	public static void delete(String name) {
		if(rs != null) {
			try {
				RecordStore.deleteRecordStore(name);
			}
			catch(RecordStoreNotFoundException rsnfe) {
				rsnfe.printStackTrace();
			}
			catch(RecordStoreException rse) {
				rse.printStackTrace();
			}
		}
		rs = null;
	}
	
	public static String getCurrentRecordStoreName () {
		if(rs != null) {
			try {
				return rs.getName();
			}
			catch(RecordStoreNotOpenException rsnoe) {
				rsnoe.printStackTrace();
			}
		}
		return null;
	}
	
	public static void saveIntArray(int[] array) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			DataOutputStream dos = new DataOutputStream(baos);
			for(int i = 0; i < array.length; i ++) {
				dos.writeInt(array[i]);
				//System.out.println("SAVE: " + array[i]);
			}
			if(rs != null) {
				addRecord(baos.toByteArray());
			}
			dos.close();
			baos.close();
		}
		catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}
	
	public static int[] loadIntArray(int id) {
		if(rs != null) {
			try {
				int[] array = new int[MapCanvas.MAX_TRACK_POINTS];
				byte[] data = getRecord(id);
				System.out.println(id + " : " + data.length);
				ByteArrayInputStream bais = new ByteArrayInputStream(data);
				DataInputStream dis = new DataInputStream(bais);
				for(int i = 0; i < MapCanvas.MAX_TRACK_POINTS; i ++) {
					array[i] = dis.readInt();
				}
				dis.close();
				bais.close();
				return array;
			}
			catch (IOException ioe) {
				ioe.printStackTrace();
			}
		}
		return null;
	}
	
	public static int getNumRecords() {
		if(rs != null) {
			try {
				return rs.getNumRecords();
			}
			catch(RecordStoreNotOpenException rsnoe) {
				rsnoe.printStackTrace();
			}
		}
		return 0;
	}
	
	public static void saveTrack(String name, Vector track) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			DataOutputStream dos = new DataOutputStream(baos);
			dos.writeInt(rs.getNextRecordID());
			dos.writeUTF(name);
			dos.writeInt(track.size());
			for(int i = 0; i < track.size(); i ++) {
				Integer integer = (Integer)track.elementAt(i);
				System.out.println(integer.intValue());
				dos.writeInt(integer.intValue());
			}
			if(rs != null) {
				addRecord(baos.toByteArray());
			}
			dos.close();
			baos.close();
		}
		catch (RecordStoreNotOpenException rsnoe) {
			rsnoe.printStackTrace();
		}
		catch (RecordStoreException rse) {
			rse.printStackTrace();
		}
		catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}
	
	public static Vector loadTrack(int id) {
		Vector track = new Vector();
		try {
			RecordEnumeration recordEnumeration = rs.enumerateRecords(null, null, false);
			while(recordEnumeration.hasNextElement()) {
				DataInputStream in = new DataInputStream(new ByteArrayInputStream(recordEnumeration.nextRecord()));
				if(in.readInt() == id) {
					in.readUTF();
					int n = in.readInt();
					for(int i = 0; i < n; i ++) {
						Integer integer = new Integer(in.readInt());
						track.addElement(integer);
					}
					break;
				}
			}
			recordEnumeration.destroy();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return track;
	}
	
	public static Vector loadAllTrackNames() {
		Vector trackNames = new Vector();
		try {
			RecordEnumeration recordEnumeration = rs.enumerateRecords(null, null, false);
			DataInputStream in = null;
			StringBuffer strBuf = null;
			while(recordEnumeration.hasNextElement()) {
				in = new DataInputStream(new ByteArrayInputStream(recordEnumeration.nextRecord()));
				strBuf = new StringBuffer();
				strBuf.append(in.readInt()).append(".").append(in.readUTF());
				trackNames.addElement(strBuf.toString());
			}
			recordEnumeration.destroy();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return trackNames;
	}
	
	public static void deleteTrack(int id) {
		try {
			RecordEnumeration recordEnumeration = rs.enumerateRecords(null, null, false);
			while(recordEnumeration.hasNextElement()) {
				int recordId = recordEnumeration.nextRecordId();
				DataInputStream in = new DataInputStream(new ByteArrayInputStream(rs.getRecord(recordId)));
				if(in.readInt() == id) {
					rs.deleteRecord(recordId);
					break;
				}
			}
			recordEnumeration.destroy();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void saveUserLocation(SimpleLocation location) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			DataOutputStream dos = new DataOutputStream(baos);
			location.setId(rs.getNextRecordID());
			dos.writeInt(location.getId());
			dos.writeByte(location.getType());
			dos.writeInt(location.getX());
			dos.writeInt(location.getY());
			dos.writeUTF(Util.decodeCharacters(location.getName()));
			if(rs != null) {
				addRecord(baos.toByteArray());
			}
			dos.close();
			baos.close();
		}
		catch (RecordStoreNotOpenException rsnoe) {
			rsnoe.printStackTrace();
		}
		catch (RecordStoreException rse) {
			rse.printStackTrace();
		}
		catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}
	
	public static Vector loadUserLocations() {
		Vector userLocations = new Vector();
		try {
			RecordEnumeration recordEnumeration = rs.enumerateRecords(null, null, false);
			DataInputStream in = null;
			if(recordEnumeration.hasNextElement()) {
				in = new DataInputStream(new ByteArrayInputStream(recordEnumeration.nextRecord()));
				for(int i = 0; i < MapDrawer.getMidlet().getSettings().getNumberOfUserLocations(); i ++) {
					SimpleLocation location = new SimpleLocation();
					location.setId(in.readInt());
					//location.setType(LayerConfig.LAYER_OTHER_LOCATION_TYPE);
					location.setType(in.readByte() & 0xFFFF);
					location.setX(in.readInt());
					location.setY(in.readInt());
					location.setName(Util.encodeStringToBytes(in.readUTF()));
					userLocations.addElement(location);
					
					/*
					 * Bo sung lo cot do nguoi dung luu
					 */
					if(location.getType() == LayerConfig.LAYER_CONSTRUCTIONSITE) {
						int segmentId = Util.findClosestSegment2(location.getX(), location.getY());
						if(segmentId != -1) {
							MapCanvas.constructionSiteSegmentIds.addElement(new Integer(segmentId));
						}
					}
				}
			}
			recordEnumeration.destroy();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return userLocations;
	}
	
	public static void deleteUserLocation(int id) {
		try {
			RecordEnumeration recordEnumeration = rs.enumerateRecords(null, null, false);
			while(recordEnumeration.hasNextElement()) {
				int recordId = recordEnumeration.nextRecordId();
				DataInputStream in = new DataInputStream(new ByteArrayInputStream(rs.getRecord(recordId)));
				if(in.readInt() == id) {
					rs.deleteRecord(recordId);
					break;
				}
			}
			recordEnumeration.destroy();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void saveUserLocations(Vector locations) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			DataOutputStream dos = new DataOutputStream(baos);
			SimpleLocation location = null;
			System.out.println("USER LOCATIONS = " + locations.size());
			for(int i = 0; i < locations.size(); i ++) {
				location = (SimpleLocation)locations.elementAt(i);
				dos.writeInt(location.getId());
				dos.writeByte(location.getType());
				dos.writeInt(location.getX());
				dos.writeInt(location.getY());
				dos.writeUTF(Util.decodeCharacters(location.getName()));
			}
			if(rs != null) {
				addRecord(baos.toByteArray());
			}
			dos.close();
			baos.close();
		}
		catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}
}
